﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UserInputWizard.WebReference;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;

namespace UserInputWizard
{
    enum TheStatus
    {
        None,
        Login,
        Input,
        Check,
        Setting,
        Update
    }
    public partial class MainForm : Form
    {
        //ステータス
        TheStatus m_status = TheStatus.None;
        public MainForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// On The mainform onload
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //ユーザ情報一覧クリア
            lst_user.Items.Clear();
            cbb_server.SelectedIndex = 0;
            //画面初期化
            InitUi(m_status);
        }

        /// <summary>
        /// 画面初期化処理
        /// </summary>
        /// <param name="status"></param>
        private void InitUi(TheStatus status)
        {
            group_step1.Enabled = false;
            group_step2.Enabled = false;
            group_step3.Enabled = false;
            group_step4.Enabled = false;
            group_step5.Enabled = false;
            switch (status)
            {
                case TheStatus.None:
                    group_step1.Enabled = true;
                    group_step2.Enabled = false;
                    group_step3.Enabled = false;
                    group_step4.Enabled = false;
                    group_step5.Enabled = false;
                    break;
                case TheStatus.Login:
                    group_step1.Enabled = true;
                    group_step2.Enabled = true;
                    group_step3.Enabled = false;
                    group_step4.Enabled = false;
                    group_step5.Enabled = false;
                    break;
                case TheStatus.Input:
                    group_step1.Enabled = true;
                    group_step2.Enabled = true;
                    group_step3.Enabled = true;
                    group_step4.Enabled = false;
                    group_step5.Enabled = false;
                    break;
                case TheStatus.Check:
                    group_step1.Enabled = true;
                    group_step2.Enabled = true;
                    group_step3.Enabled = true;
                    group_step4.Enabled = true;
                    group_step5.Enabled = true;
                    break;
                case TheStatus.Setting:
                    group_step1.Enabled = true;
                    group_step2.Enabled = true;
                    group_step3.Enabled = true;
                    group_step4.Enabled = true;
                    group_step5.Enabled = true;
                    break;
                default:
                    group_step1.Enabled = true;
                    group_step2.Enabled = true;
                    group_step3.Enabled = true;
                    group_step4.Enabled = true;
                    group_step5.Enabled = true;
                    break;
            }
        }

        /// <summary>
        /// 「ログイン」ボタンを押下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_login_Click(object sender, EventArgs e)
        {
            if (txt_user.Text == "")
            {
                MessageBox.Show("ユーザ名がNULLです。");
                return;
            }
            if (txt_pwd.Text == "")
            {
                MessageBox.Show("パスワードがNULLです。");
                return;
            }
            if (Salesforce.getInstance().Login(txt_user.Text, txt_pwd.Text, cbb_server.SelectedIndex == 1))
            {
                m_status = TheStatus.Login;
                MessageBox.Show("ログインしました。");
                cbb_profile.DataSource = Salesforce.getInstance().GetProfile();
                cbb_profile.DisplayMember = "Name";
            }
            else
            {
                m_status = TheStatus.None;
                MessageBox.Show("ログイン失敗しました。");
            }
            InitUi(m_status);
        }

        /// <summary>
        /// ユーザ情報を導入する
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_input_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "CSFファイル|*.CSV";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                if (LoadUserInfo(dlg.FileName))
                {
                    m_status = TheStatus.Input;
                }
                else
                {
                    m_status = TheStatus.Login;
                }
                InitUi(m_status);
            }
        }
        
        /// <summary>
        /// ユーザ情報CSVファイルを読み込む
        /// </summary>
        /// <param name="csvFile"></param>
        internal bool LoadUserInfo(string csvFile)
        {
            lst_user.Items.Clear();
            bool isSuccess = true;
            try
            {
                using (StreamReader sr = new StreamReader(csvFile,Encoding.Default))
                {
                    string info = sr.ReadLine();
                    while (!sr.EndOfStream)
                    {
                        info = sr.ReadLine();
                        string [] infos = info.Split(',');
                        if (infos.Length != 5)
                        {
                            Log.WriteLine("下記のユーザ情報が間違いました。");
                            Log.WriteLine(info);
                            isSuccess = false;
                        }
                        if (isSuccess)
                        {
                            foreach (string i in infos)
                            {
                                if (String.IsNullOrEmpty(i))
                                {
                                    Log.WriteLine("下記のユーザ情報が間違いました。");
                                    Log.WriteLine(info);
                                    isSuccess = false;
                                    break;
                                }
                            }
                        }
                        if (!isSuccess)
                        {
                            Log.WriteLine("ユーザ情報を導入失敗しました。");
                            MessageBox.Show("ユーザ情報を導入失敗しました。");
                            return isSuccess;
                        }
                        //「姓」設定
                        ListViewItem item = new ListViewItem(infos[0]);
                        //「名」設定
                        item.SubItems.Add(infos[1]);
                        //「ユーザ名」設定
                        item.SubItems.Add(infos[2]);
                        //「電子メール」設定
                        item.SubItems.Add(infos[3]);
                        //「パスワード」設定
                        item.SubItems.Add(infos[4]);
                        //「エラーメッセージ」を設定
                        item.SubItems.Add("");
                        lst_user.Items.Add(item);
                    }
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                isSuccess = false;
                Log.WriteLine("ユーザ情報を導入失敗しました。");
                Log.WriteLine(ex.Message);
            }
            return isSuccess;
        }

        /// <summary>
        /// 「チェック」ボタン押下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_check_Click(object sender, EventArgs e)
        {
            //既存ユーザ情報を取得する
            Hashtable existUsers = Salesforce.getInstance().GetUser();
            //成功フラグ
            bool isSuccess = true;
            foreach (ListViewItem item in lst_user.Items)
            {
                string username = item.SubItems[2].Text;
                ///・ユーザ名重複チェック
                if (existUsers.ContainsKey(username))
                {
                    //エラーメッセージを設定
                    item.SubItems[4].Text = "ユーザ名重複";
                    isSuccess = false;
                    continue;
                }
                ///・ユーザ名フォーマットチェック
                if (!isMailFormat(username))
                {
                    //エラーメッセージを設定
                    item.SubItems[4].Text = "ユーザ名フォーマット間違い";
                    isSuccess = false;
                    continue;
                }
                ///・メールフォーマットチェック
                if (!isMailFormat(item.SubItems[3].Text))
                {
                    //エラーメッセージを設定
                    item.SubItems[4].Text = "メールフォーマット間違い";
                    isSuccess = false;
                    continue;
                }
                ///・パスワード複雑性チェック
            }

            if (isSuccess)
            {
                m_status = TheStatus.Check;
                MessageBox.Show("ユーザ情報をチェックしました。OKです。");
            }
            else
            {
                m_status = TheStatus.Input;
                Log.WriteLine("ユーザ情報をチェックエラー発生しました。");
                MessageBox.Show("ユーザ情報をチェック失敗しました。");
            }
            InitUi(m_status);
        }

        /// <summary>
        /// メールフォーマットチェック
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public bool isMailFormat(string input)
        {
            Regex r = new Regex(@"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b",RegexOptions.IgnoreCase);
            return r.IsMatch(input);
        }

        /// <summary>
        /// 「更新」ボタン押下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_update_Click(object sender, EventArgs e)
        {
            //プロファイルを取得する
            Profile profile = Salesforce.getInstance().GetProfileByName(cbb_profile.Text);
            if (profile == null)
            {
                MessageBox.Show("プロファイルが存在しません。");
                return;
            }

            //ユーザリストを作成
            List<User> newUsers = new List<User>();
            foreach (ListViewItem item in lst_user.Items)
            {
                //姓,名,ユーザ名,電子メール,プロファイル
                User user = Salesforce.getInstance().CreateUser(
                    item.Text,              //姓
                    item.SubItems[1].Text,  //名
                    item.SubItems[2].Text,  //ユーザ名
                    item.SubItems[3].Text,  //電子メール
                    profile);               //プロファイル
                newUsers.Add(user);
            }

            //ユーザをデプロイ
            if (!Salesforce.getInstance().DeployUser(newUsers))
            {
                MessageBox.Show("ユーザをデプロイ失敗しました。");
                return;
            }

            //既存ユーザを取得
            Hashtable existUsers = Salesforce.getInstance().GetUser();

            //ユーザパスワードを設定
            foreach (ListViewItem item in lst_user.Items)
            {
                //ユーザ名
                string username = item.SubItems[2].Text;
                //パスワード
                string password = item.SubItems[4].Text;

                if(existUsers.ContainsKey(username))
                {
                    User user = (User)existUsers[username];
                    if (!Salesforce.getInstance().SetPassword(user, password))
                    {
                        MessageBox.Show("パスワードを設定失敗しました。\n" + username);
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("ユーザが存在しません。\n"+username);
                    return;
                }
            }

            MessageBox.Show("ユーザ情報をデプロイ完了。");
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(Log.LogFile);
        }
    }
}
